package com.fudan.es;

import java.time.ZoneId;

import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.nested.ReverseNestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;

import com.fudan.es.aggs.ConstString;
import com.fudan.es.entity.DimensionPack;
import com.fudan.es.entity.FieldMeta;

public class Aggs {

	private static String MISSING = "Missing";

	public static AggregationBuilder nested(String name,String  path) {
		return new NestedAggregationBuilder(name, path);
	}

	public static AggregationBuilder reverse(String name,String  path) {
		return new ReverseNestedAggregationBuilder(name).path(path);
	}

	public static AggregationBuilder reverse(String name) {
		return new ReverseNestedAggregationBuilder(name);
	}

	public static AggregationBuilder matchAllFilter() {
		return new FilterAggregationBuilder(ConstString.ALL_FILTER, QueryBuilders.matchAllQuery());
	}

	public static AggregationBuilder filter(String name,QueryBuilder query) {
		return new FilterAggregationBuilder(name, query);
	}

	public static TermsAggregationBuilder terms(FieldMeta field) {
		return new TermsAggregationBuilder(ConstString.TERMS_TAG+"$"+field.getId(), resolveForFieldType(field.getType())).field(field.getName());
	}


	public static TermsAggregationBuilder terms(String name,ValueType type,String field) {
		return new TermsAggregationBuilder(name, type).field(field);
	}

	public static TermsAggregationBuilder terms(String name,String field) {
		return terms(name,field,10);
	}

	public static TermsAggregationBuilder terms(String name,String field,int size) {
		return new TermsAggregationBuilder(name, ValueType.STRING).field(field).size(size);
	}

	public static TermsAggregationBuilder termsWithMissing(String name,String field) {
		return new TermsAggregationBuilder(name, ValueType.STRING).field(field).missing(MISSING);
	}

	public static AvgAggregationBuilder avg(FieldMeta field) {
		return new AvgAggregationBuilder(ConstString.AVG_TAG+"$"+field.getId()).field(field.getName());
	}

	public static AvgAggregationBuilder avg(String name,String field) {
		return new AvgAggregationBuilder(name).field(field);
	}

	public static AggregationBuilder sum(FieldMeta field) {
		return new SumAggregationBuilder(ConstString.SUM_TAG+"$"+field.getId()).field(field.getName());
	}

	public static AggregationBuilder sum(String name,String field) {
		return new SumAggregationBuilder(name).field(field);
	}

	public static AggregationBuilder date(FieldMeta field,DateHistogramInterval level) {
		return new DateHistogramAggregationBuilder(ConstString.DATE_TAG+"$"+field.getId()).field(field.getName()).dateHistogramInterval(level).timeZone(ZoneId.systemDefault());
	}
	
	public static AggregationBuilder date(String name,String field,DateHistogramInterval level) {
		return new DateHistogramAggregationBuilder(name).field(field).dateHistogramInterval(level).timeZone(ZoneId.systemDefault());
	}

	public static AggregationBuilder date(DimensionPack dimension) {
		DateHistogramInterval interval = new DateHistogramInterval(dimension.getInterval());
		return new DateHistogramAggregationBuilder(dimension.getField().getName()).field(dimension.getField().getName()).dateHistogramInterval(interval);
	}


   public static ValueType resolveForFieldType(String type) {
        switch (type) {
        	case "text":
        	case "keyword":
            case "string":  return ValueType.STRING;
            case "double":
            case "float":   return ValueType.DOUBLE;
            case "long":
            case "integer":
            case "short":
            case "byte":    return ValueType.LONG;
            case "date":    return ValueType.DATE;
            case "ip":      return ValueType.IP;
            case "boolean": return ValueType.BOOLEAN;
            default:
                // 默认尝试用string
            	return ValueType.STRING;
        }
    }
}
